package com.common.base.action;

import java.lang.reflect.ParameterizedType;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;

import com.common.base.entity.BaseEntity;
import com.common.base.exceptions.DaoException;
import com.common.base.service.BaseService;
import com.common.base.util.ServiceHelper;
import com.common.tag.Page;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;
import com.opensymphony.xwork2.Preparable;


public class BaseAction<T extends BaseEntity> extends ActionSupport implements Preparable, ModelDriven<T> {

	private static final long serialVersionUID = 1L;
	
	protected T entity;
	protected List<T> entities;
	protected BaseService<T> baseService;
	protected Class<T> entityClass; // model's Class
	protected String entityClassName; // model's ClassName
	private Map<String, String> qu = new HashMap<String, String>(); // 放置查询参数的Map对象

	@SuppressWarnings("unchecked")
	public BaseAction() {
		Object superClassType = getClass().getGenericSuperclass();
		
		if (superClassType instanceof ParameterizedType) {
			entityClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
			entityClassName = entityClass.getSimpleName();
		}
	}
	
	@SuppressWarnings("unchecked")
	public BaseService<T> getBaseService() {
		BaseService<T> baseService = null;
		if (this.entityClass != null) {
			baseService = (BaseService<T>) ServiceHelper.findBean(StringUtils.uncapitalize(entityClassName)	+ "Service");
		} else {
			baseService = this.baseService;
		}
		return baseService;
	}
	public void setBaseService(BaseService<T> baseService) {
		this.baseService = baseService;
	}
	
	public Map<String, String> getQu() {
		return qu;
	}

	public void setQu(Map<String, String> qu) {
		this.qu = qu;
	}	
	
	public List<T> getEntities() {
		return entities;
	}
	
	public T getEntity() {
		return entity;
	}
	
	public void setEntity(T entity) {
		this.entity = entity;
	}

	protected Long getSid() {
		HttpServletRequest request = ServletActionContext.getRequest();
		String sid = request.getParameter("sid");
		if (StringUtils.isNotEmpty(sid)) {
			return new Long(sid);
		} else {
			return null;
		}
	}
	
	public T getModel() {	
		return entity;
	}

	public void prepare() throws Exception {	
		if (entityClass == null) {
			return;
		}
		if (getSid() != null) {
		    entity = getBaseService().findBySid(getSid());
			if (entity == null)
				throw new IllegalArgumentException("error: sid not exist");
		} else {
			entity = entityClass.newInstance();
		}
	}
	


	//通用方法
	
	public String insert() throws DaoException {
		if(null == getSid()){
			// String a=  this.getText("welcome"); 国际化
	
				getBaseService().insert(entity);
	
		}else{
			getBaseService().update(entity);
		}
		// entities = findAll();
		return "success";
	}
	
	public String execute() {
		return "success";
	}
	
	
	public final String findByParams() throws Exception {
		
		Map<String, Object> params = new HashMap<String, Object>();
		params.put("flag1", "1");
		entities = getBaseService().findByParams(params);
		System.out.println("findByParams + entities = " + entities.size());
		return "success";
	}
	
	
	
	
	/**
	 * 以下程序 待用
	 */
	protected HttpServletRequest getRequest(){
		return ServletActionContext.getRequest();
	}

	protected HttpServletResponse getResponse(){
		return ServletActionContext.getResponse();
	}
	
	protected Object findBean(String beanId){
		return ServiceHelper.findBean(beanId);
	}



	public final static String PARAMS_KEY_PAGE_CUR="pageCur"; // 当前页数
	public final static String PARAMS_KEY_PAGE_SIZE="pageSize"; //每页显示的行数
	protected final static int PAGE_SIZE = 10; //默认每页显示10行
	
	/**
	 * 在调用Serivce的分页方法之前，预处理分页相关参数
	 * @param request
	 */
	protected Map<String, Object> preparePageParams(HttpServletRequest request) throws Exception{
		
		String query = request.getQueryString();
		String pageURL = request.getServletPath();
		
		if (query != null && query.length() > 0) {
			pageURL += "?" + query;
		}
		request.setAttribute("contextURL", URLEncoder.encode(pageURL, "UTF-8"));
		request.setAttribute("pageURL", request.getContextPath() + pageURL);
		
		Map<String, Object> params = new HashMap<String, Object>();

		Set<Map.Entry<String, String>> p = qu.entrySet();
		for (Map.Entry<String, String> me : p) {
			String name = me.getKey();
			String value = me.getValue();
			if (StringUtils.isNotEmpty(value)) {
				params.put(name, value);
			}
		}

		int pageCur = 1; //当前页数
		int pageSize = PAGE_SIZE; //每页显示的行数 默认是10行
		
		if (!StringUtils.isEmpty((String) qu.get(PARAMS_KEY_PAGE_CUR))) {
			try {
				pageCur = Integer.parseInt((String) qu.get(PARAMS_KEY_PAGE_CUR));
			} catch (RuntimeException e) {
			}
		}
		params.put(PARAMS_KEY_PAGE_CUR, new Integer(pageCur));
		

		if (!StringUtils.isEmpty((String) qu.get(PARAMS_KEY_PAGE_SIZE))) {
			try {
				pageSize = Integer.parseInt((String) qu.get(PARAMS_KEY_PAGE_SIZE));
			} catch (RuntimeException e) {
			}
		}
		params.put(PARAMS_KEY_PAGE_SIZE, new Integer(pageSize));
		
		return params;
	}

	/**
	 * 分页查询方法
	 * @return
	 * @throws Exception
	 */
	public String findByPage() throws Exception {
		HttpServletRequest request = ServletActionContext.getRequest();
		Map<String, Object> params = this.preparePageParams(request);
		
		Page<T> page = getBaseService().findByPage(params, (Integer)params.get(PARAMS_KEY_PAGE_CUR), (Integer)params.get(PARAMS_KEY_PAGE_SIZE));
		entities = page.getResultList();
		request.setAttribute("page", page);
		onFindByPage(request);
		return "success";
	}
	
	/**
	 * 定义一个回调方法，默认基类没有任何实现，子类根据需要覆写该方法实现为findByPage方法补充额外数据
	 * 主要用于分页页面初始化用于转移相关的对象
	 */
	protected void onFindByPage(HttpServletRequest request){}
	
}
